#!/bin/bash

# 获取所有合适的块设备列表（排除只读、虚拟设备等）
DEVICES=$(ls /sys/block | grep -E '^(sd|hd|vd|xvd|nvme|mmcblk)' | sort -u)

if [ -z "$DEVICES" ]; then
    echo "未找到合适的块设备！" >&2
    exit 1
fi

echo "检测到以下设备将进行优化："
echo "$DEVICES" | sed 's/^/ - \/dev\//'
echo "-------------------------------------"

# 处理每个设备
for DEVICE in $DEVICES; do
    DEV_PATH="/sys/block/${DEVICE}"
    SCHED_PATH="${DEV_PATH}/queue/scheduler"
    
    # 跳过只读设备
    if [[ $(< "${DEV_PATH}/ro") -eq 1 ]]; then
        echo "[${DEVICE}] 跳过：设备为只读"
        continue
    fi
    
    # 跳过没有调度器的设备
    if [ ! -f "$SCHED_PATH" ]; then
        echo "[${DEVICE}] 跳过：无调度器支持"
        continue
    fi
    
    # 检测设备类型 (0=SSD, 1=HDD)
    ROTATIONAL=$(< "${DEV_PATH}/queue/rotational")
    DEV_TYPE=$([ "$ROTATIONAL" -eq 0 ] && echo "SSD" || echo "HDD")
    
    # 获取当前支持的调度器
    AVAIL_SCHED=$(grep -oP '\[.*\]' < "$SCHED_PATH" | tr -d '[]')
    CURRENT_SCHED=$(grep -oP '\[.*?\]' < "$SCHED_PATH" | tr -d '[]')
    
    echo "[${DEVICE}] 类型: ${DEV_TYPE}, 当前调度器: ${CURRENT_SCHED}"
    
    # 设置优化调度器
    if [ "$ROTATIONAL" -eq 0 ]; then
        # SSD优化策略
        PREFERRED_SCHEDS=("none" "noop" "kyber" "bfq" "mq-deadline" "deadline")
        TARGET_SCHED=""
        for sched in "${PREFERRED_SCHEDS[@]}"; do
            if [[ "$AVAIL_SCHED" == *"$sched"* ]]; then
                TARGET_SCHED="$sched"
                break
            fi
        done
        
        # 设置队列深度（SSD可更高）
        echo 256 > "${DEV_PATH}/queue/nr_requests" 2>/dev/null
    else
        # HDD优化策略
        PREFERRED_SCHEDS=("mq-deadline" "bfq" "kyber" "deadline")
        TARGET_SCHED=""
        for sched in "${PREFERRED_SCHEDS[@]}"; do
            if [[ "$AVAIL_SCHED" == *"$sched"* ]]; then
                TARGET_SCHED="$sched"
                break
            fi
        done
        
        # 设置队列深度（HDD适中）
        echo 128 > "${DEV_PATH}/queue/nr_requests" 2>/dev/null
        
        # Deadline参数调优
        if [[ "$TARGET_SCHED" == *"deadline"* ]]; then
            IOSCHED_PATH="${DEV_PATH}/queue/iosched"
            if [ -d "$IOSCHED_PATH" ]; then
                # 读请求优先处理（毫秒）
                echo 100 > "$IOSCHED_PATH/read_expire" 2>/dev/null
                # 写请求超时时间（毫秒）
                echo 5000 > "$IOSCHED_PATH/write_expire" 2>/dev/null
                # 读请求优先级倍数
                echo 2 > "$IOSCHED_PATH/writes_starved" 2>/dev/null
            fi
        fi
    fi
    
    # 应用调度器设置
    if [ -n "$TARGET_SCHED" ]; then
        echo "$TARGET_SCHED" > "$SCHED_PATH"
        echo "  -> 设置调度器: $(grep -oP '\[.*?\]' < "$SCHED_PATH" | tr -d '[]')"
    else
        echo "  -> 警告：未找到推荐的调度器，保持当前设置"
    fi
    
    # 应用额外优化参数
    echo 2 > "${DEV_PATH}/queue/nomerges" 2>/dev/null      # 禁用合并请求
    echo 64 > "${DEV_PATH}/queue/read_ahead_kb" 2>/dev/null # 减少预读
    
    # 显示优化结果
    echo "  | 队列深度: $(< "${DEV_PATH}/queue/nr_requests")"
    echo "  | 预读大小: $(< "${DEV_PATH}/queue/read_ahead_kb") KB"
    echo "  | 请求合并: $(< "${DEV_PATH}/queue/nomerges") (0=启用 2=禁用)"
    if [[ "$TARGET_SCHED" == *"deadline"* ]] && [ -d "${DEV_PATH}/queue/iosched" ]; then
        echo "  | 读超时: $(< "${DEV_PATH}/queue/iosched/read_expire") ms"
        echo "  | 写超时: $(< "${DEV_PATH}/queue/iosched/write_expire") ms"
    fi
    echo "-------------------------------------"
done

echo "所有设备优化完成！"
